<template>
  <div class="cus-tree-node">
    <div class="cus-tree-entry">
      <div class="cus-tree-main" @click="nodeHandle(node, $event)">
        <div>
          <i
            v-if="(node.child && node.child.length > 0) || node.pid == 0"
            class="cus-tree-icon"
            :class="{ 'el-icon-folder': !nodeOpenTag, 'el-icon-folder-opened': nodeOpenTag }"
          ></i>
          <i v-if="(!node.child || node.child.length <= 0) && node.pid != 0" class="cus-tree-icon el-icon-document"></i>
        </div>
        <div>
          <div v-show="nodeEditTag" @click.stop>
            <el-input size="mini" v-model="node.title"></el-input>
          </div>
          <div v-show="!nodeEditTag" class="cus-tree-txt">
            <div v-if="node.child && node.child.length > 0" style="font-weight: bolder">
              {{ node.title }}
            </div>
            <div v-else-if="!node.child || node.child.length <= 0">
              {{ node.title }}
            </div>
          </div>
        </div>
      </div>
      <!-- 编辑栏 -->
      <div class="tree-handle-tool">
        <i v-show="nodeEditTag && node.title.trim().length > 0" class="el-icon-check" @click="submitHandle"></i>
        <i v-show="nodeEditTag" class="el-icon-close" @click="closeHandle"></i>

        <i v-show="!nodeEditTag&&authFilter(permissionObj, 'add')"
           class="el-icon-plus" @click="nodeCreate"></i>
        <i v-show="!nodeEditTag&&authFilter(permissionObj, 'update')"
           class="el-icon-edit-outline" @click="nodeEdit"></i>
        <!--    最外层父级不可删除    -->
        <i v-show="!nodeEditTag&&authFilter(permissionObj, 'delete')&&node.pid!=0"
           class="el-icon-delete" @click="nodeDelete"></i>
      </div>
    </div>
    <!-- 递归轮询出下一级的树节点 -->
    <el-collapse-transition>
      <div v-show="nodeOpenTag" class="cus-child-container" v-if="node.child && node.child.length > 0">
        <el-collapse-transition v-for="child in node.child" :key="child.id">
          <div class="cus-child-node" v-show="nodeOpenTag">
            <cusTreeNode :node="child" :treeData="treeData" :addHanlde="addHanlde" :delHandle="delHandle" :editHandle="editHandle"></cusTreeNode>
          </div>
        </el-collapse-transition>
      </div>
    </el-collapse-transition>
  </div>
</template>

<script>
import {mapGetters} from "vuex";

/**
 * @description 树形节点
 * @param {Object}  node	        节点的数据
 * @param {Boolean}  allOpen	    子节点全部打开
 * @param {Array}  treeData       树型组件的数据
 * @param {Boolean}  noLine		    开启树形的线条
 *
 * @event {Function()} addHanlde  添加的操作
 * @event {Function()} delHandle  删除的操作
 * @event {Function()} editHandle 修改的操作
 */
export default {
  name: 'cusTreeNode',
  props: {
    node: {
      type: Object,
      default: {},
    },
    allOpen: {
      type: Boolean,
      default: true,
    },
    treeData: {
      type: Array,
      default: [],
    },
    noLine: {
      type: Boolean,
      default: false,
    },
    addHanlde: {
      type: Function,
      default: () => {},
    },
    delHandle: {
      type: Function,
      default: () => {},
    },
    editHandle: {
      type: Function,
      default: () => {},
    },
  },
  data: () => {
    return {
      nodeOpenTag: false, // 节点打开标志
      nodeEditTag: false, // 节点编辑标志
      oldNodeTitle: '',
    }
  },
  computed:{
    ...mapGetters(['userAuthList']),
    permissionObj(){
      if(this.userAuthList&&this.userAuthList.length>0){
        return this.authListFilter(this.userAuthList,'customManagement', 'modulelist')
      }
    }
  },
  methods: {
    inputHandle() {},
    // 子级节点的展开操作
    nodeHandle(node, e) {
      this.nodeOpenTag = !this.nodeOpenTag
    },
    // 节点创建
    nodeCreate() {
      let treeArr = this.treeToArray(this.treeData)
      let addNode = treeArr.filter((t) => t.id == '')
      if (addNode && addNode[0]) {
        return  this.$message.error('已有未确定的添加')
      }
      this.recQueryHandle(this.treeData, 'create')
    },
    // 节点删除
    nodeDelete() {
      this.delHandle(this.node)
    },
    // 节点编辑
    nodeEdit() {
      this.nodeEditTag = true
      this.oldNodeTitle = this.node.title
    },
    // 提交操作
    submitHandle() {
      this.recQueryHandle(this.treeData, 'submit')
    },
    // 关闭操作
    closeHandle() {
      this.nodeEditTag = false
      this.recQueryHandle(this.treeData, 'close')
    },
    //根据字段筛选去掉重复对象获取长度
    //keysToCheck:提取需要比较的字段作为键值（['id', 'name']）
    //arr:去重数组
    fieldsArr(arr,keysToCheck){
      // 创建一个空集合
      let set = new Set();

      for (let obj of arr) {
        let keyValue = '';

        for (let key of keysToCheck) {
          if (!obj.hasOwnProperty(key)) continue;

          keyValue += `${obj[key]}`;
        }

        if (set.has(keyValue)) {
          console.log(`${keyValue} 重复`);
        } else {
          set.add(keyValue);
        }
      }
      return set.size
    },
    // 对自己节点进行递归操作
    recQueryHandle(treeData, tag) {
      // 当前操作的节点
      let curNode = this.node
      treeData.forEach((item) => {
        if (item.id === curNode.id) {
          // 添加元素
          if (tag === 'create') {
            // 先查询是否已有追加的元素
            if (!curNode.child) {
              this.$set(item, 'child', [])
            }
            // 查询当前同层->新增且未提交的节点
            let addTag = item.child.filter((t) => t.id == '')
            if (addTag.length > 0) {
              this.$message.error('已有未确定的添加')
              return
            }
            // 添加节点
            // item.child.push({ title: '新建子节点', id: '', edit: true, pid: item.id })
            item.child.push({ title: '', id: '', edit: true, pid: item.id })
          }
          // 删除元素
          else if (tag === 'del') {
            let index = treeData.findIndex((t) => t.id == curNode.id)
            treeData.splice(index, 1)
          }
          // 编辑元素
          else if (tag === 'edit') {
            this.oldNodeTitle = this.node.title
          }
          // 节点的提交事件
          else if (tag == 'submit') {
            // id为空为添加数据
            if (curNode.id == '') {
              var existIndex = item.title.indexOf('/')
              if (existIndex != -1) return  this.$message.error('不允许存在 / 字符存在')
              // 查询当前同层->同级添加项中，添加相同的内容模块
              const arr = treeData.filter(sItm=>sItm.pid==curNode.pid)
              const len = this.fieldsArr(arr,['title']);
              // console.log('arr', arr);
              // console.log('len', len);
              if (len&&arr&&arr.length) {
                if (arr.length!=len) {
                  this.$message.error('该模块存在')
                  return
                }
              }
              this.addHanlde(curNode)
            } else {
              // id 不为空为编辑数据
              if (item.title === this.oldNodeTitle) return (this.nodeEditTag = false)
              // 特殊字符查询
              var existIndex = item.title.indexOf('/')
              if (existIndex != -1) return  this.$message.error('不允许存在 / 字符存在')
              this.editHandle(curNode)
            }
          }
          // 节点的修改或添加状态的关闭状态
          else if (tag == 'close') {
            // id 若为空则删除
            if (curNode.id == '') {
              treeData.pop()
            } else {
              item.title = this.oldNodeTitle
            }
          }
          return
        }
        if (item.child) {
          this.recQueryHandle(item.child, tag)
        }
      })
    },
    // 获取扁平化的数据
    treeToArray(tree) {
      var res = []
      for (const item of tree) {
        const { child, ...i } = item
        if (child && child.length) {
          res = res.concat(this.treeToArray(child))
        }
        res.push(i)
      }
      return res
    },
    layerTips(title) {},
  },
  watch: {
    node() {
      this.nodeEditTag = this.node.edit
    },
  },
  created() {
    this.nodeOpenTag = this.allOpen
    this.nodeEditTag = this.node.edit
  },
  mounted() {
    this.oldNodeTitle = this.node.title
  },
}
</script>

<style lang="less" scoped>
/* 树节点 */
.cus-tree-node {
  line-height: 30px;
  padding-left: 23px;
  position: relative;
}

.cus-tree-node:not(:last-child) > .cus-child-container::after {
  content: '';
  border-left: 1px dashed #ccc;
  position: absolute;
  left: 30.5px;
  top: 29.5px;
  height: calc(100% - 30px);
}

/* 子节点的连线 */
.cus-child-node:not(:last-child) > ::after {
  content: '';
  border-left: 1px dashed #ccc;
  position: absolute;
  left: 7.5px;
  top: 0;
  height: 100%;
}

.cus-child-node:last-child > ::after {
  content: '';
  border-left: 1px dashed #ccc;
  position: absolute;
  left: 7.5px;
  top: -1px;
  height: 16px;
}

.cus-child-node .cus-tree-icon::after {
  content: '';
  border-top: 1px dashed #ccc;
  width: 60%;
  position: absolute;
  top: 7.2px;
  left: -14px;
}

/* 单个书节点的显示主体 */
.cus-tree-entry {
  height: 30px;
  display: flex;
  line-height: 30px;
  cursor: pointer;
}

.cus-tree-entry:hover .tree-handle-tool {
  line-height: 30px;
  height: 30px;
  display: block;
}

.cus-tree-main {
  display: flex;
  font-size: 15px;

  div:first-child {
    padding-right: 8px;
  }
}

/* 树的操作栏工具 */
.tree-handle-tool {
  display: none;
  padding-left: 10px;

  i {
    padding: 0 5px;
    font-weight: 9;
  }

  i:hover {
    opacity: 0.5;
  }
}

.cus-tree-icon {
  background-color: #ffffff;
  color: #ffb800;
  z-index: 2;
  position: relative;
}

/* 树节点的标题 */
.cus-tree-txt:hover {
  text-decoration: underline;
  color: #a8a8a8;
}
</style>

